'use strict';
const fs = require('fs');
const os = require('os');

const DbProvider = require('./db/db_provider');
const Processor = require('./base_processor');
const Logger = require('../lib/log/logger');
const StringUtil = require('./util/string_util');
const { ExcelColumns } = require('./base_processor');
const Sequelize = require('sequelize');
const path = require('path');
const LogUtil = require('../lib/util/log_util');

class NewProcessor extends Processor {
  constructor(filePath) {
    super(filePath, 'NewProcessor');
    this.db = DbProvider.getNewDb();
    this.logger = new Logger('NewProcessor', LogUtil.getFileLogWriter('NewProcessor', path.basename(this.outputFilePath)));
  }

  /**
     * 业务逻辑
     * read >> process >> write
     * @return {String} 输出文件路径
     */
  async process() {
    this.logger.clear();
    const dataList = this.read();
    if (dataList && dataList.length > 0) {
      let tempLogInfo = '';
      for (const data of dataList) {
        let filterData = data[ExcelColumns.NEW_PATH];
        this.getRecordClass(data[ExcelColumns.TYPE], data);
        this.getRecordType(data[ExcelColumns.CLASS], data);
        this.getLibrasries(data[ExcelColumns.LIBRARY], data);

        if (!filterData) {
          this.logger.info(`新栏目路径为空，无法查询的数据:${data[ExcelColumns.NEW_COLUMN]}`);
          data[ExcelColumns.NEW_COLUMN_ID] = null;
          data[ExcelColumns.NEW_COLUMN_CODE] = null;
          continue;
        }
        if (filterData.indexOf('-') !== -1) {
          filterData = filterData.replace(/-/g, '/');
        }
        if (filterData.indexOf('>') !== -1) {
          filterData = filterData.replace(/>/g, '/');
        }
        if (filterData.indexOf('\\') !== -1) {
          filterData = filterData.replace(/\\/g, '/');
        }
        await this.db.query('select id , code from columns where name = ? and level_name = ? and edit_record = 0', {
          raw: true,
          replacements: [ data[ExcelColumns.NEW_COLUMN], filterData ],
          type: Sequelize.QueryTypes.SELECT,
        }).then(columnResult => {
          if (!columnResult || columnResult.length === 0) {
            if (tempLogInfo !== data[ExcelColumns.NEW_PATH]) {
              this.logger.info(`新栏目路径未查询到对应的数据:${data[ExcelColumns.NEW_PATH]}`);
              tempLogInfo = data[ExcelColumns.NEW_PATH];
            }
            data[ExcelColumns.NEW_COLUMN_ID] = null;
            data[ExcelColumns.NEW_COLUMN_CODE] = null;
          } else {
            data[ExcelColumns.NEW_COLUMN_ID] = columnResult[0].id;
            data[ExcelColumns.NEW_COLUMN_CODE] = columnResult[0].code;
          }
        });
      }
      const output = dataList;
      this.getResJson(output);
      this.write(output);

      return this.outputFilePath;
    }
  }

  getResJson(dataList) {
    const newGroupList = [];
    const groupList = this.groupBy(dataList, function(item) {
      return [ item[ExcelColumns.OLD_COLUMN_ID] ];
    });
    for (let i = 1; i < groupList.length; i++) {
      const groupSubList = groupList[i];
      const groupSub = groupSubList.find(xx => xx.ofClass !== null || xx.ofType !== null) ? groupSubList.find(xx => xx.ofClass !== null || xx.ofType !== null) : groupSubList[0];
      if (groupSub[ExcelColumns.NEW_COLUMN_ID]) {
        const outPutItem = {
          name: groupSub[ExcelColumns.OLD_COLUMN_NEW],
          id: groupSub[ExcelColumns.OLD_COLUMN_ID],
          siteId: groupSub[ExcelColumns.OLD_COLUMN_SITEID],
          contentType: this.getContentType(groupSub[ExcelColumns.CATEGORY_ONE]),
          ofType: groupSub[ExcelColumns.OF_TYPE],
          ofClass: groupSub[ExcelColumns.OF_CLASS],
          libraries: groupSub[ExcelColumns.LIBRARIES],
          newColumns: [],
        };
        const tempColumnList = [];
        groupSubList.forEach(item => {
          if (item[ExcelColumns.NEW_COLUMN_ID]) {
            const newColumn = {
              name: item[ExcelColumns.NEW_COLUMN],
              code: item[ExcelColumns.NEW_COLUMN_CODE],
              id: item[ExcelColumns.NEW_COLUMN_ID],
              isMain: this.getIsMain(item[ExcelColumns.MAIN]),
            };
            if (newColumn.isMain !== null) {
              tempColumnList.push(newColumn);
            }
          }
        });
        outPutItem.newColumns = this.arrayUnique(tempColumnList, 'id');
        if (outPutItem.newColumns.length !== 0) {
          if (outPutItem.newColumns.filter(x => x.isMain === true).length > 1) {
            let count = 0;
            outPutItem.newColumns.forEach(p => {
              if (p.code !== 'zfhcxjsbwj' && count === 0 && p.isMain === true) {
                p.isMain = false;
                count += 1;
              }
            });
          }
          newGroupList.push(outPutItem);
        }
      }
    }
    const isMainFalseOnly = newGroupList.filter(m => m.newColumns.length >= 1
        &&
        !m.newColumns.find(item => item.isMain === true));
    this.logger.info(`输出的只有isMain为false的json:${JSON.stringify(isMainFalseOnly)}`);
    this.logger.info(`输出的写入文件的json:${JSON.stringify(newGroupList)}`);
    this.outputJson(JSON.stringify(newGroupList));
  }

  outputJson(json) {
    fs.writeFileSync('./logs/newJson.json', json + os.EOL, { flag: 'w' });
  }

  groupBy(array, f) {
    const groups = {};
    array.forEach(function(o) {
      const group = JSON.stringify(f(o));
      groups[group] = groups[group] || [];
      groups[group].push(o);
    });
    return Object.keys(groups).map(function(group) {
      return groups[group];
    });
  }

  arrayUnique(arr, name) {
    const hash = {};
    return arr.reduce(function(item, next) {
      hash[next[name]] ? '' : hash[next[name]] = true && item.push(next);
      return item;
    }, []);
  }

  getContentType(contentType) {
    switch (contentType) {
      case '文章':
        return 1;
      case '文件':
        return 2;
      case '标准':
        return 3;
      default:
        return null;
    }
  }

  getIsMain(mainColumn) {
    switch (mainColumn) {
      case '主':
        return true;
      case '引用':
        return false;
      default:
        return true;
    }
  }

  getRecordClass(classColumn, data) {
    if (!classColumn) {
      data[ExcelColumns.OF_CLASS] = null;
      return;
    }
    switch (classColumn) {
      case '法律':
        data[ExcelColumns.OF_CLASS] = 1;
        break;
      case '行政法规':
        data[ExcelColumns.OF_CLASS] = 2;
        break;
      case '行政处罚':
        data[ExcelColumns.OF_CLASS] = 3;
        break;
      case '部令':
        data[ExcelColumns.OF_CLASS] = 4;
        break;
      case '通知':
        data[ExcelColumns.OF_CLASS] = 5;
        break;
      case '通报':
        data[ExcelColumns.OF_CLASS] = 6;
        break;
      case '公示':
        data[ExcelColumns.OF_CLASS] = 7;
        break;
      case '公告':
        data[ExcelColumns.OF_CLASS] = 8;
        break;
      case '函':
        data[ExcelColumns.OF_CLASS] = 9;
        break;
      case '中共中央国务院文件':
        data[ExcelColumns.OF_CLASS] = 10;
        break;
      case '其他':
        data[ExcelColumns.OF_CLASS] = 20;
        break;
      default:
        break;
    }
  }

  getRecordType(typeColumn, data) {
    if (!typeColumn) {
      data[ExcelColumns.OF_TYPE] = null;
      return;
    }

    switch (typeColumn) {
      case '普通':
        data[ExcelColumns.OF_TYPE] = 1;
        break;
      case '行政许可':
        data[ExcelColumns.OF_TYPE] = 2;
        break;
      case '行政处罚':
        data[ExcelColumns.OF_TYPE] = 3;
        break;
      case '标准公告':
        data[ExcelColumns.OF_TYPE] = 4;
        break;
      default:
        break;
    }
  }

  getLibrasries(libColumn, data) {
    data[ExcelColumns.LIBRARIES] = [];
    if (!libColumn) {
      return;
    }
    const libraryDataList = StringUtil.splitTypeColumn(libColumn);

    for (const libraryData of libraryDataList) {
      switch (libraryData) {
        case '文件库':
          data[ExcelColumns.LIBRARIES].push(1);
          break;
        case '文告库':
          data[ExcelColumns.LIBRARIES].push(2);
          break;
        case '政策法规库':
          data[ExcelColumns.LIBRARIES].push(3);
          break;
        case '标准库':
          data[ExcelColumns.LIBRARIES].push(4);
          break;
        default:
          break;
      }
    }
  }
}

module.exports = NewProcessor;
